// Copyright (C) 2022 Linlexiao
#include "mainwindow.h"

#include <QDebug>
#include <QLabel>
#include <QMessageBox>
#include <QSpacerItem>

#include "dialog/exportproblemdialog.h"
#include "dialog/importproblemdialog.h"
#include "pailabel.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget* parent)
    : QMainWindow(parent), ui(new Ui::MainWindow) {
    ui->setupUi(this);
    ui->textEdit->setReadOnly(true);
    PaiLabel::init();
    setWindowState(Qt::WindowMaximized);
    ui->horizontalSpacer->changeSize(SPACER, SPACER);
    ui->horizontalSpacer_2->changeSize(SPACER, SPACER,
                                       QSizePolicy::MinimumExpanding);
    connect(ui->action_importProblem, &QAction::triggered, this,
            &MainWindow::onImportProblem);
    connect(ui->action_exportProblem, &QAction::triggered, this,
            &MainWindow::onExportProblem);
    connect(ui->action_pointRefernce, &QAction::triggered, this,
            &MainWindow::onPointRefernce);
    connect(ui->action_fuReference, &QAction::triggered, this,
            &MainWindow::onFuRefernce);

    fuReferenceWidget = new FuReferenceWidget(this);
    ui->verticalLayout_2->addWidget(fuReferenceWidget);

    pointReferenceWidget = new PointReferenceWidget(this);
    ui->verticalLayout_2->addWidget(pointReferenceWidget);

    //    auto spacer = new
    //    QSpacerItem(1,1,QSizePolicy::Minimum,QSizePolicy::MinimumExpanding);
    //    ui->verticalLayout_2->addItem(spacer);
    initLabels();
    newProblem();
    nowSolving = true;
}

MainWindow::~MainWindow() { delete ui; }

void MainWindow::initLabels() {
    for (int i = 0; i < 13; i++) {
        auto* lb = new PaiLabel(this);
        lb->setPai("B");
        ui->horizontalLayout->insertWidget(i, lb);
        leftLabels.push_back(lb);
    }

    auto* lb = new PaiLabel(this);
    problemGenerator = new ProblemGenerator;
    lb->setPai("B");
    ui->horizontalLayout->insertWidget(14, lb);
    agariLabel = lb;

    for (int i = 0; i < 16; i++) {
        auto* lb = new PaiLabel(this);
        ui->horizontalLayout->addWidget(lb);
        rightLabels.push_back(lb);
    }

    //    QSpacerItem* x= new QSpacerItem(0,0,QSizePolicy::MinimumExpanding);
    for (int i = 1; i <= 5; i++) {
        auto* lb = new PaiLabel(this);
        lb->setPai("B");
        ui->gridLayout->addWidget(lb, 0, i);
        doraLabels.push_back(lb);
    }
    for (int i = 1; i <= 5; i++) {
        auto* lb = new PaiLabel(this);
        lb->setPai("B");
        ui->gridLayout->addWidget(lb, 1, i);
        uraLabels.push_back(lb);
    }
    //    qDebug()<<"left"<<leftLabels;
    //    qDebug()<<"right"<<rightLabels;
    //    qDebug()<<"dora"<<doraLabels;
    //    qDebug()<<"ura"<<uraLabels;
}

void MainWindow::newProblem() {
    auto p = problemGenerator->generate();
    setProblem(p);
    //    setProblem(Problem(p.toSTextEdit));
    qDebug() << problem.toString();
}

void MainWindow::setProblem(const Problem& p) {
    ui->label_5->setText("输入答案：");
    ui->pushButton->setText("提交答案");
    nowSolving = true;
    problem = p;
    //先删除所有的牌
    for (auto x : leftLabels) x->removePai();
    for (auto x : rightLabels) x->removePai();
    for (auto x : doraLabels) x->removePai();
    for (auto x : uraLabels) x->removePai();
    agariLabel->removePai();
    switch (problem.ans.pointType) {
        case OYARON:
            ui->textEdit_2->setPlaceholderText("请直接输入点数");
            break;
        case KORON:
            ui->textEdit_2->setPlaceholderText("请直接输入点数");
            break;
        case OYATSUMO:
            ui->textEdit_2->setPlaceholderText("请输入每个人支付点数");
            break;
        case KOTSUMO:
            ui->textEdit_2->setPlaceholderText(
                "请分别输入子、亲家需支付点数，中间用空格分割");
            break;
    }

    ui->textEdit->clear();
    ui->textEdit_2->clear();
    ui->textEdit_2->setReadOnly(false);
    // 1.处理手牌
    int l1 = problem.hand.length();
    for (int i = 0; i < 13; i++) {
        if (i < l1) {
            leftLabels[i]->setPai(problem.hand[i].toString());
        } else {
            leftLabels[i]->removePai();
        }
    }
    // 2.处理和了牌
    agariLabel->setPai(problem.agariPai.toString());
    // 3.处理副露
    int furuCnt = 0;
    for (auto b : problem.furu) {
        auto ps = b.getPai();
        switch (b.blockType) {
            case SEQUENCE:
                for (int i = 0; i < 3; i++) {
                    if (i == 0)
                        rightLabels[furuCnt++]->setPai("H" + ps[i].toString());
                    else
                        rightLabels[furuCnt++]->setPai(ps[i].toString());
                }
                break;
            case TRIPLET:
                for (int i = 0; i < 3; i++) {
                    if (i == 0)
                        rightLabels[furuCnt++]->setPai("H" + ps[i].toString());
                    else
                        rightLabels[furuCnt++]->setPai(ps[i].toString());
                }
                break;
            case QUAD:
                if (b.isOpen) {
                    for (int i = 0; i < 4; i++) {
                        if (i == 0)
                            rightLabels[furuCnt++]->setPai("H" +
                                                           ps[i].toString());
                        else
                            rightLabels[furuCnt++]->setPai(ps[i].toString());
                    }
                } else {  //暗杠
                    rightLabels[furuCnt++]->setPai("B");
                    for (int i = 1; i <= 2; i++) {
                        rightLabels[furuCnt++]->setPai(ps[i].toString());
                    }
                    rightLabels[furuCnt++]->setPai("B");
                }
                break;
        }
    }

    if (furuCnt == 0) {
        ui->horizontalSpacer_2->changeSize(0, 0, QSizePolicy::MinimumExpanding);
    } else {
        ui->horizontalSpacer_2->changeSize(SPACER, SPACER,
                                           QSizePolicy::MinimumExpanding);
    }
    // 4.处理标志
#define TEST_FLAG(x, y) \
    if (problem.flag.testFlag(x)) ui->textEdit->insertPlainText(y)
    auto rnd = QRandomGenerator::global();
    auto x = rnd->bounded(1, 5);
    QString roundNumber;
    if (x == 1) {
        roundNumber = "一";
    } else if (x == 2) {
        roundNumber = "二";
    } else if (x == 3) {
        roundNumber = "三";
    } else if (x == 4) {
        roundNumber = "四";
    }
    TEST_FLAG(FIELD_EAST, "东" + roundNumber + "局 ");
    TEST_FLAG(FIELD_SOUTH, "南" + roundNumber + "局 ");
    TEST_FLAG(FIELD_WEST, "西" + roundNumber + "局 ");
    TEST_FLAG(FIELD_NORTH, "北" + roundNumber + "局 ");
    TEST_FLAG(SEAT_EAST, "东家 ");
    TEST_FLAG(SEAT_SOUTH, "南家 ");
    TEST_FLAG(SEAT_WEST, "西家 ");
    TEST_FLAG(SEAT_NORTH, "北家 ");
    TEST_FLAG(TSUMO, "自摸\n");
    TEST_FLAG(RON, "荣和\n");
    TEST_FLAG(RIICHI, "立直\n");
    TEST_FLAG(DOUBLE_RIICHI, "双立直\n");
    TEST_FLAG(IPPATSU, "一发\n");
    TEST_FLAG(HAITEI_RAOYUE, "海底捞月\n");
    TEST_FLAG(HOUTEI_RAOYUI, "河底摸鱼\n");
    TEST_FLAG(RINNSHANN_KAIHOU, "岭上开花\n");
    TEST_FLAG(CHANKAN, "抢杠\n");
    TEST_FLAG(TENHOU, "天和\n");
    TEST_FLAG(CHIIHOU, "地和\n");
    // 5.处理宝牌
    int doraLength = problem.dora.length();
    int uraLength = problem.ura.length();
    for (int i = 0; i < doraLength; i++) {
        doraLabels[i]->setPai(problem.dora[i].toString());
    }
    for (int i = doraLength; i < 5; i++) {
        doraLabels[i]->setPai("B");
    }
    for (int i = 0; i < uraLength; i++) {
        uraLabels[i]->setPai(problem.ura[i].toString());
    }
    for (int i = uraLength; i < 5; i++) {
        uraLabels[i]->setPai("B");
    }
}

void MainWindow::resizeEvent(QResizeEvent* event) {
    QMainWindow::resizeEvent(event);
}

void MainWindow::onClick() {
    if (nowSolving) {
        nowSolving = false;
        ui->pushButton->setText("下一题");
        ui->label_5->setText("答案显示：");
        QString userAns = ui->textEdit_2->toPlainText();
        ui->textEdit_2->clear();
        ui->textEdit_2->setReadOnly(true);
        for (const auto& s : problem.ans.yaku) {
            ui->textEdit_2->append(s);
        }
        ui->textEdit_2->append("");
        if (problem.ans.isYakuman) {
            ui->textEdit_2->append(QString::number(problem.ans.han) + "倍役满");
        } else {
            qDebug() << problem.ans.manType;
            switch (problem.ans.manType) {
                case NOMANGAN:
                    ui->textEdit_2->append(
                        QString::number(problem.ans.han) + "番 " +
                        QString::number(problem.ans.fu) + "符");
                    break;
                case MANGAN:
                    if (problem.ans.han != 5) {
                        ui->textEdit_2->append(
                            QString::number(problem.ans.han) + "番 " +
                            QString::number(problem.ans.fu) + "符 满贯");
                    } else {
                        ui->textEdit_2->append(
                            QString::number(problem.ans.han) + "番 满贯");
                    }
                    break;
                case HANEMAN:
                    ui->textEdit_2->append(QString::number(problem.ans.han) +
                                           "番 跳满");
                    break;
                case BAIMAN:
                    ui->textEdit_2->append(QString::number(problem.ans.han) +
                                           "番 倍满");
                    break;
                case SANBAIMAN:
                    ui->textEdit_2->append(QString::number(problem.ans.han) +
                                           "番 三倍满");
                    break;
                case KAZOEYUAKUMAN:
                    ui->textEdit_2->append(QString::number(problem.ans.han) +
                                           "番 累计役满");
                    break;
            }
        }
        bool correct = true;
        if (problem.ans.pointType == OYARON || problem.ans.pointType == KORON) {
            ui->textEdit_2->append(QString("您输入的答案为：%1")
                                       .arg(QString::number(userAns.toInt())));
            ui->textEdit_2->append("正确答案：" +
                                   QString::number(problem.ans.point1));
            auto u = userAns.toInt();
            if (u != problem.ans.point1) correct = false;
        } else if (problem.ans.pointType == OYATSUMO) {
            auto u = userAns.toInt();
            ui->textEdit_2->append(QString("您输入的答案为：%1 ALL")
                                       .arg(QString::number(userAns.toInt())));
            ui->textEdit_2->append(
                "正确答案：" + QString::number(problem.ans.point1) + " ALL");
            if (u != problem.ans.point1) correct = false;
        } else if (problem.ans.pointType == KOTSUMO) {
            auto x = userAns.split(" ");
            int a1, a2;
            a1 = x[0].toInt();
            if (x.length() >= 2)
                a2 = x[1].toInt();
            else
                a2 = 0;
            ui->textEdit_2->append(
                QString("您输入的答案为：%1 / %2")
                    .arg(QString::number(a1), QString::number(a2)));
            ui->textEdit_2->append("正确答案：" +
                                   QString::number(problem.ans.point1) + " / " +
                                   QString::number(problem.ans.point2));
            if (x.length() < 2)
                correct = false;
            else {
                if (a1 != problem.ans.point1) correct = false;
                if (a2 != problem.ans.point2) correct = false;
            }
        }

        if (correct) {
            ui->textEdit_2->append("<div style=\"color:#0f0\">答案正确</div>");
        } else {
            ui->textEdit_2->append("<div style=\"color:red\">答案错误</div>");
        }
        ui->textEdit_2->append("");
    } else {
        newProblem();
    }
}

void MainWindow::onImportProblem() {
    ImportProblemDialog dialog;
    if (dialog.exec()) {
        auto ls = dialog.code.split(sep);
        if (ls.length() != 3) {
            QMessageBox::critical(this, "失败", "代码错误");
            return;
        }
        if (ls[0].toInt() != VERSION) {
            QMessageBox::critical(this, "失败", "不兼容的版本");
            return;
        }
        if (ls[1].toInt() != ls[2].length()) {
            QMessageBox::critical(this, "失败",
                                  "代码长度错误，请检查是否复制完全");
            return;
        }

        bool ok;
        Problem p(ls[2], ok);
        if (ok) {
            p.calculateResult();
            setProblem(p);
        } else {
            QMessageBox::critical(this, "失败", "代码错误");
            return;
        }
    }
}

void MainWindow::onExportProblem() {
    auto pcode = problem.toString();
    auto code = QString("%1%4%2%4%3")
                    .arg(QString::number(VERSION),
                         QString::number(pcode.length()), pcode, sep);
    ExportProblemDialog dialog(code);
    dialog.exec();
}

void MainWindow::onPointRefernce(bool b)

{
    if (b) {
        pointReferenceWidget->show();
    } else {
        pointReferenceWidget->hide();
    }
}

void MainWindow::onFuRefernce(bool b) {
    if (b) {
        fuReferenceWidget->show();
    } else {
        fuReferenceWidget->hide();
    }
}
